package com.kgc.basicprovider.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itextpdf.forms.PdfAcroForm;
import com.itextpdf.forms.fields.PdfFormField;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.properties.TextAlignment;
import com.kgc.basic.annotation.DetailEntity;
import com.kgc.basic.annotation.PdfFieldMapping;
import com.kgc.basic.annotation.PdfTemplateConfig;
import com.kgc.basic.annotation.Validation;
import com.kgc.basic.pojo.Customer;
import com.kgc.basic.util.ResponseMsg;
//import com.kgc.basicprovider.feign.SalesInvoiceImportExportFeign;
import com.kgc.basicprovider.feign.*;
import com.kgc.basicprovider.service.CustomerService;
import com.kgc.basicprovider.service.ImportExportService;
import com.kgc.cgapi.pojo.CGXJPojo;
import com.kgc.cgapi.pojo.PurchaseInvoice;
import com.kgc.store.pojo.CostAdjustment;
import com.kgc.store.pojo.InStore;
import com.kgc.store.pojo.InStoreDetail;
import com.kgc.xs.pojo.SalesInvoice;
import com.kgc.xs.pojo.SalesReturn;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Field;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import java.text.SimpleDateFormat;

import static org.springframework.core.log.LogFormatUtils.formatValue;


@Service
public class ImportExportServiceImpl implements ImportExportService {

    private static final Logger logger = LoggerFactory.getLogger(ImportExportServiceImpl.class);

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private CustomerService customerService;

    @Autowired
    private PurchaseInvoiceImportExportFeign purchaseInvoiceImportExportFeign;

    @Autowired
    private SalesInvoiceImportExportFeign salesInvoiceImportExportFeign;

    @Resource
    private CGXJImportFeign cgXJImportFeign;

    @Autowired
    private SalesReturnFeign  salesReturnFeign;

    @Autowired
    private ProChangeFeign proChangeFeign;

    @Autowired
    private InStoreFeign inStoreFeign;

    @Autowired
    private  InStoreDetailFeign inStoreDetailFeign;

    @Override
    @Transactional
    public ResponseMsg importEntities(MultipartFile file, Class<?> entityClass, String uniqueField, String flag) {
        ResponseMsg msg = new ResponseMsg();
        try {

            // 检查是否有明细表字段
            Field detailField = null;
            DetailEntity detailAnnotation = null;
            for (Field field : entityClass.getDeclaredFields()) {
                if (field.isAnnotationPresent(DetailEntity.class)) {
                    detailField = field;
                    detailAnnotation = field.getAnnotation(DetailEntity.class);
                    break;
                }
            }

            // 读取主表数据
            List<Object> mainEntities = new ArrayList<>();
            EasyExcel.read(file.getInputStream(), entityClass, new PageReadListener<>(dataList -> {
                mainEntities.addAll(dataList);
            })).sheet(detailField != null ? "Main" : entityClass.getSimpleName()).doRead();

            if (mainEntities.isEmpty()) {
                msg.setCode("600");
                msg.setMsg("主表数据为空");
                return msg;
            }

            // 如果有明细表，读取明细表数据
            List<Object> allDetails = new ArrayList<>();
            if (detailField != null) {
                EasyExcel.read(file.getInputStream(), detailAnnotation.detailClass(), new PageReadListener<>(dataList -> {
                    allDetails.addAll(dataList);
                })).sheet("Details").doRead();
            }

//            // 读取 Excel 文件
//            List<Object> entities = new ArrayList<>();
//            EasyExcel.read(file.getInputStream(), entityClass, new PageReadListener<>(dataList -> {
//                entities.addAll(dataList);
//            })).sheet().doRead();
//
//            if (entities.isEmpty()) {
//                msg.setCode("600");
//                msg.setMsg("Excel文件无数据");
//                return msg;
//            }

            // 校验和处理每条记录
            for (int i = 0; i < mainEntities.size(); i++) {
                Object mainEntity = mainEntities.get(i);
                int rowNum = i + 2;

                // 唯一性校验（通过 Feign 调用）
                if (uniqueField != null && !uniqueField.isEmpty()) {
                    Field uniqueFieldObj = entityClass.getDeclaredField(uniqueField);
                    uniqueFieldObj.setAccessible(true);
                    Object uniqueValue = uniqueFieldObj.get(mainEntity);
                    if (uniqueValue != null) {
                        ResponseMsg checkMsg = null;
                        if (entityClass == SalesInvoice.class) {
                            // 销售发票单据编号重复校验
                            checkMsg = salesInvoiceImportExportFeign.selectSalesInvoiceByCode(uniqueValue.toString());
                        } else if (entityClass == Customer.class) {
                            // 客户重复校验
                            checkMsg = customerService.selectCustomerByCode(uniqueValue.toString());
                        } else if (entityClass == PurchaseInvoice.class) {
                            checkMsg = purchaseInvoiceImportExportFeign.selectPurchaseInvoiceByCode(uniqueValue.toString());
                        }
                        if (checkMsg != null && "301".equals(checkMsg.getCode())) {
                            msg.setCode("301");
                            msg.setMsg(String.format("第%d行：%s %s 已存在", rowNum, uniqueField, uniqueValue));
                            return msg;
                        }
                    }
                }

                // 设置默认值
                setDefaultValues(mainEntity);

                // 动态校验字段
                ResponseMsg validateMsg = validateEntity(mainEntity, rowNum, entityClass);
                if (!"200".equals(validateMsg.getCode())) {
                    return validateMsg;
                }

                // 关联明细表数据
                if (detailField != null) {
                    // 存储与当前主表记录关联的明细数据
                    List<Object> relatedDetails = new ArrayList<>();
                    // 通过反射获取主表实体类的唯一字段（如："code"），用于匹配主表和明细表
                    Field uniqueFieldObj = entityClass.getDeclaredField(uniqueField);
                    // 设置唯一字段为可访问，解除私有访问限制
                    uniqueFieldObj.setAccessible(true);
                    // 获取当前主表记录（mainEntity）的唯一字段值（如："XSFP-20250510-001"）
                    Object uniqueValue = uniqueFieldObj.get(mainEntity);

                    // 获取明细表实体类（在@DetailEntity注解中的detailClass标识获取，例如：SalesInvoiceDetail.class）
                    // 并通过反射获取明细表中用于关联的字段（如："invoiceCode"）
                    Field relationField = detailAnnotation.detailClass().getDeclaredField(detailAnnotation.relationField());
                    relationField.setAccessible(true);

                    for (Object detail : allDetails) {
                        // 通过反射获取当前明细记录的关联字段值（例如 invoiceCode 的值）
                        Object detailRelationValue = relationField.get(detail);

                        // 判断主表唯一字段值和明细表关联字段值是否非空，且两者是否相等
                        if (uniqueValue != null && detailRelationValue != null && uniqueValue.toString().equals(detailRelationValue.toString())) {
                            relatedDetails.add(detail);
                        }
                    }

                    // 通过反射设置明细表数据到主表
                    detailField.setAccessible(true);
                    detailField.set(mainEntity, relatedDetails);


                }

            }


            // 插入数据
            for (Object entity : mainEntities) {
                ResponseMsg insertMsg = null;
                if (entityClass == SalesInvoice.class) {

                    // 构建Map
                    Map<String, Object> map = new HashMap<>();
                    map.put("salesInvoice", entity);
                    if (detailField != null) {
                        Field detailsField = entityClass.getDeclaredField(detailField.getName());
                        detailsField.setAccessible(true);
                        map.put("details", detailsField.get(entity));
                    }
                    insertMsg = salesInvoiceImportExportFeign.insertSalesInvoice(map);
                } else if (entityClass == Customer.class) {
                    insertMsg = customerService.insertCustomer((Customer) entity);
                } else if (entityClass == PurchaseInvoice.class) {
                    // 构建Map
                    Map<String, Object> map = new HashMap<>();
                    map.put("purchaseInvoice", entity);
                    if (detailField != null) {
                        Field detailsField = entityClass.getDeclaredField(detailField.getName());
                        detailsField.setAccessible(true);
                        map.put("details", detailsField.get(entity));
                    }
                    insertMsg = purchaseInvoiceImportExportFeign.insertPurchaseInvoice(map);
                } else if (entityClass == CGXJPojo.class) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("pojo", entity);
                    if (detailField != null) {
                        Field detailsField = entityClass.getDeclaredField(detailField.getName());
                        detailsField.setAccessible(true);
                        map.put("list", detailsField.get(entity));
                    }
                    insertMsg = cgXJImportFeign.inputCGXJ(map);
                    //TODO
                }
                else if (entityClass == SalesReturn.class) {
                    //构建map
                    Map<String, Object> map = new HashMap<>();
                    map.put("salesReturn", entity);
                    if (detailField != null) {
                        Field detailsField = entityClass.getDeclaredField(detailField.getName());
                        detailsField.setAccessible(true);
                        map.put("details", detailsField.get(entity));
                    }
                    insertMsg=salesReturnFeign.insertSalesReturn(map);
                }
                else if (entityClass == CostAdjustment.class) {
                    //构建map
                    Map<String, Object> map = new HashMap<>();
                    map.put("costAdjustment", entity);
                    if (detailField != null) {
                        Field detailsField = entityClass.getDeclaredField(detailField.getName());
                        detailsField.setAccessible(true);
                        map.put("details", detailsField.get(entity));
                    }
                    insertMsg=proChangeFeign.importProChange(map);
                }
                else if (entityClass == InStore.class) {
                   InStore inStore =  (InStore)entity;
                    if (detailField != null) {
                        Field detailsField = entityClass.getDeclaredField(detailField.getName());
                        detailsField.setAccessible(true);
                        for (Object o : (ArrayList) detailsField.get(entity)) {
                            InStoreDetail inStoreDetail=   (InStoreDetail) o;
                            inStoreDetailFeign.addInStoreDetail(inStoreDetail);
                        }
                    }
                    inStoreFeign.addInStore(inStore);
                }

                if (insertMsg != null && !"200".equals(insertMsg.getCode())) {
                    return insertMsg;
                }

            }
            msg.setCode("200");
            msg.setMsg("导入成功");
            return msg;
        } catch (Exception e) {
            logger.error("ImportExportServiceImpl importEntities error", e);
            msg.setCode("500");
            msg.setMsg("导入失败：" + e.getMessage());
            return msg;
        }
    }


    @Override
    public ResponseMsg exportEntities(Map<String, Object> map, Class<?> entityClass, String orderBy) {
        ResponseMsg msg = new ResponseMsg();
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            List<Object> entities = new ArrayList<>();

            // 检查是否有选中行
            if (map.containsKey("selectedRows") && map.get("selectedRows") instanceof List) {
                List<?> selectedRows = (List<?>) map.get("selectedRows");
                if (!selectedRows.isEmpty()) {
                    // 将前端传递的选中行转换为目标实体类
                    entities = selectedRows.stream()
                            .map(row -> objectMapper.convertValue(row, entityClass))
                            .collect(Collectors.toList());
                } else {
                    msg.setCode("600");
                    msg.setMsg("未选择任何数据进行导出");
                    return msg;
                }
            }

            // 检查是否存在明细表字段
            Field detailField = null;
            DetailEntity detailAnnotation = null;
            for (Field field : entityClass.getDeclaredFields()) {
                if (field.isAnnotationPresent(DetailEntity.class)) {
                    detailField = field;
                    detailAnnotation = field.getAnnotation(DetailEntity.class);
                    break;
                }
            }

            if (detailField != null) {
                // 使用 ExcelWriter 写入多个工作表
                ExcelWriter excelWriter = EasyExcel.write(baos)
                        .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                        .build();

                // 写入主表数据到 "Main" 工作表
                WriteSheet mainSheet = EasyExcel.writerSheet("Main")
                        .head(entityClass)
                        .build();
                excelWriter.write(entities, mainSheet);

                // 提取并写入明细表数据到 "Details" 工作表
                Class<?> detailClass = detailAnnotation.detailClass();
                List<Object> allDetails = new ArrayList<>();
                for (Object entity : entities) {
                    detailField.setAccessible(true);
                    Object detailsObj = detailField.get(entity);
                    if (detailsObj instanceof List) {
                        allDetails.addAll((List<?>) detailsObj);
                    }
                }
                WriteSheet detailsSheet = EasyExcel.writerSheet("Details")
                        .head(detailClass)
                        .build();
                excelWriter.write(allDetails, detailsSheet);

                // 完成写入
                excelWriter.finish();
            } else {
                // 如果没有明细表字段，写入单一工作表
                EasyExcel.write(baos, entityClass)
                        .sheet(entityClass.getSimpleName())
                        .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                        .doWrite(entities);
            }

            msg.setCode("200");
            msg.setMsg("导出成功");
            msg.setData(Base64.getEncoder().encodeToString(baos.toByteArray()));  //Base64编码成字符串
            return msg;
        } catch (Exception e) {
            logger.error("ImportExportServiceImpl exportEntities error", e);
            msg.setCode("500");
            msg.setMsg("导出失败：" + e.getMessage());
            return msg;
        }
    }

    @Override
    public ResponseMsg downloadTemplate(Class<?> entityClass) {
        ResponseMsg msg = new ResponseMsg();
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            // 检查是否有明细表字段
            Field detailField = null;
            DetailEntity detailAnnotation = null;
            for (Field field : entityClass.getDeclaredFields()) {
                if (field.isAnnotationPresent(DetailEntity.class)) {
                    detailField = field;
                    detailAnnotation = field.getAnnotation(DetailEntity.class);
                    break;
                }
            }

            if (detailField != null) {
                ExcelWriter excelWriter = EasyExcel.write(baos)
                        .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                        .build();

                WriteSheet mainSheet = EasyExcel.writerSheet("Main")        //主表
                        .head(entityClass)
                        .build();
                excelWriter.write(new ArrayList<>(), mainSheet);

                WriteSheet detailsSheet = EasyExcel.writerSheet("Details")  //明细表
                        .head(detailAnnotation.detailClass())
                        .build();
                excelWriter.write(new ArrayList<>(), detailsSheet);

                excelWriter.finish();
            } else {
                EasyExcel.write(baos, entityClass)
                        .sheet(entityClass.getSimpleName())
                        .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                        .doWrite(new ArrayList<>());
            }

            msg.setCode("200");
            msg.setMsg("模板下载成功");
            msg.setData(Base64.getEncoder().encodeToString(baos.toByteArray()));
            return msg;
        } catch (Exception e) {
            logger.error("ImportExportServiceImpl downloadTemplate error", e);
            msg.setCode("500");
            msg.setMsg("模板下载失败：" + e.getMessage());
            return msg;
        }
    }

    @Override
    public ResponseMsg printEntitiesToPDF(Map<String, Object> map, Class<?> entityClass, String orderBy) {
        ResponseMsg msg = new ResponseMsg();
        try {
            Object row = map.get("row");
            Object entity = objectMapper.convertValue(row, entityClass);
            logger.info("ImportExportServiceImpl printEntitiesToPDF 转换后的数据:{}", entity);
            if (entity == null) {
                msg.setCode("600");
                msg.setMsg("无数据可打印");
                return msg;
            }

            // 获取模板配置
            PdfTemplateConfig templateConfig = entityClass.getAnnotation(PdfTemplateConfig.class);
            if (templateConfig == null) {
                msg.setCode("500");
                msg.setMsg("实体类未配置 PdfTemplateConfig 注解");
                return msg;
            }
            String templatePath = templateConfig.templatePath();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            // 使用 iText 生成 PDF
            // 创建一个PdfWriter对象，将文档写入到文件中
            PdfWriter writer = new PdfWriter(baos);
            // 创建一个PdfReader对象，将文档读取出来
            PdfReader reader = new PdfReader(templatePath);
            // 初始化一个PdfDocument对象
            PdfDocument pdf = new PdfDocument(reader, writer);
            // 初始化一个Document对象
            Document document = new Document(pdf);

            // 设置中文字体
            PdfFont font = PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H");
//            document.setFont(font);

            // 获取表单字段
            PdfAcroForm form = PdfAcroForm.getAcroForm(pdf, true);
            Map<String, PdfFormField> fields = form.getFormFields();

            // 填充主表字段
            for (Field field : entityClass.getDeclaredFields()) {
                field.setAccessible(true);
                PdfFieldMapping mapping = field.getAnnotation(PdfFieldMapping.class);
                if (mapping != null) {
                    String templateField = mapping.templateField();
                    String format = mapping.format();
                    Object value = field.get(entity);
                    String formattedValue = formatValue(value, format);
                    if (fields.containsKey(templateField)) {
                        fields.get(templateField).setValue(formattedValue);
                    } else {
                        logger.warn("Template field {} not found in PDF", templateField);
                    }
                }
            }

            // 填充明细表字段
            Field detailField = Arrays.stream(entityClass.getDeclaredFields())
                    .filter(f -> f.isAnnotationPresent(DetailEntity.class))
                    .findFirst()
                    .orElse(null);

            if (detailField != null) {
                detailField.setAccessible(true);
                Object detailsObj = detailField.get(entity);
                if (detailsObj instanceof List) {
                    List<?> details = (List<?>) detailsObj;
                    if (!details.isEmpty()) {
                        int fieldsPerRow = 4; // 每行字段数
                        int baseIndex = 1; // 模板从 fill1 开始
                        int rowCount = Math.min(details.size(), 2); // 2为模板支持的明细数据行数
                        for (int i = 0; i < rowCount; i++) {
                            Object detail = details.get(i);
                            for (Field detailFieldItem : detail.getClass().getDeclaredFields()) {
                                detailFieldItem.setAccessible(true);
                                PdfFieldMapping detailMapping = detailFieldItem.getAnnotation(PdfFieldMapping.class);
                                if (detailMapping != null) {
                                    String baseField = detailMapping.templateField().replace("_", ""); // 移除下划线以解析
                                    int fieldIndex = Integer.parseInt(baseField.replace("fill", "")); // 获取基础索引
                                    String dynamicField = "fill_" + (baseIndex + (i * fieldsPerRow) + (fieldIndex - 1)); // 动态生成
                                    Object detailValue = detailFieldItem.get(detail);
                                    String formattedDetailValue = formatValue(detailValue, detailMapping.format());
                                    if (fields.containsKey(dynamicField)) {
                                        fields.get(dynamicField).setValue(formattedDetailValue);
                                    }




//                                    String templateField = detailMapping.templateField(); // 例如 fill_1, fill_2
//                                    Object detailValue = detailFieldItem.get(detail);
//                                    String formattedDetailValue = formatValue(detailValue, detailMapping.format());
//                                    if (fields.containsKey(templateField)) {
//                                        fields.get(templateField).setValue(formattedDetailValue);
//                                    }
                                }
                            }
                        }
                    }
                }
            }

            // 刷新表单
            form.flattenFields(); // 固定字段值，防止编辑
            document.close();
            pdf.close();

            msg.setCode("200");
            msg.setMsg("PDF 生成成功");
            msg.setData(Base64.getEncoder().encodeToString(baos.toByteArray()));
            return msg;
        } catch (Exception e) {
            logger.error("ImportExportServiceImpl printEntitiesToPDF error", e);
            msg.setCode("500");
            msg.setMsg("PDF 打印失败：" + e.getMessage());
            return msg;
        }
    }

    // 辅助方法：格式化值
    private String formatValue(Object value, String format) {
        if (value == null) return "";
        if (!format.isEmpty()) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat(format);
                if (value instanceof Date) {
                    return sdf.format((Date) value);
                } else if (value instanceof String) {
                    SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
                    Date date = parser.parse((String) value);
                    return sdf.format(date);
                }
            } catch (Exception e) {
                logger.warn("Failed to format value {} with format {}", value, format);
            }
        } else if (value instanceof Date) {
            return new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format((Date) value);
        }
        return String.valueOf(value);
    }

    /**
     * 动态校验字段
     *
     * @param entity      实体对象
     * @param rowNum      行号（用于错误提示）
     * @param entityClass 实体类类型
     * @return ResponseMsg 校验结果
     */
    private ResponseMsg validateEntity(Object entity, int rowNum, Class<?> entityClass) throws IllegalAccessException {
        ResponseMsg msg = new ResponseMsg();

        // 通过反射获取所有字段
        for (Field field : entityClass.getDeclaredFields()) {
            field.setAccessible(true);  //关闭安全检查，提升反射速度
            Validation validation = field.getAnnotation(Validation.class);  //获取属性上的注解
            if (validation != null) {
                Object value = field.get(entity);

                // 必填校验
                if (validation.required() && (value == null || (value instanceof String && ((String) value).trim().isEmpty()))) {
                    msg.setCode("601");
                    msg.setMsg(String.format("第%d行：%s", rowNum, validation.message()));
                    return msg;
                }

                // 长度校验
                if (value instanceof String) {
                    String strValue = (String) value;
                    if (strValue != null) {
                        if (strValue.length() < validation.minLength()) {
                            msg.setCode("602");
                            msg.setMsg(String.format("第%d行：%s", rowNum, validation.message()));
                            return msg;
                        }
                        if (strValue.length() > validation.maxLength()) {
                            msg.setCode("603");
                            msg.setMsg(String.format("第%d行：%s", rowNum, validation.message()));
                            return msg;
                        }
                    }
                }

                // 正则表达式校验
                if (!validation.regex().isEmpty() && value instanceof String) {
                    String strValue = (String) value;
                    if (strValue != null && !Pattern.matches(validation.regex(), strValue)) {
                        msg.setCode("604");
                        msg.setMsg(String.format("第%d行：%s", rowNum, validation.message()));
                        return msg;
                    }
                }
            }
        }
        msg.setCode("200");
        return msg;
    }

    /**
     * 设置默认值（如 createDate、isDelete 等）
     *
     * @param entity 实体对象
     */
    private void setDefaultValues(Object entity) throws IllegalAccessException {
        // 通过反射获取所有字段
        for (Field field : entity.getClass().getDeclaredFields()) {
            field.setAccessible(true);
            if (field.get(entity) == null) {//为null时，为其赋默认值
                switch (field.getName()) {
                    case "createDate":
                    case "updateDate":
                    case "codeDate":
                    case "orderCreationTime":
                    case "modifyTime":
                        field.set(entity, new Date());
                        break;
                    case "isDelete":
                        field.set(entity, 0);
                        break;
                    case "createUid":
                    case "updateUid":
                        field.set(entity, 0);
                        break;
                    case "orderCreator":
                    case "modifier":
                        field.set(entity, "1");
                        break;
                    case "orderDepartment":
                        field.set(entity, "测试");
                }
            }
        }
    }
}
